package com.google.denta.aspect;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.util.StopWatch;

/**
 * @author crash
 */
@Aspect
public class BenchmarkAspect {

    /** Logger. */
    private final Logger logger = Logger.getLogger(this.getClass());

    /**
     * Pointcut handle.
     */
    @Pointcut("execution(* com.google.denta.service..*ServiceImpl.*(..))")
    public void profile() {
    }

    /**
     * Pointcut handle around action.
     * @param jp ProceedingJoinPoint aspect system
     * @return Object aspect system
     * @throws Throwable exception
     */
    @Around("profile()")
    public Object profile(final ProceedingJoinPoint jp) throws Throwable {
        final StopWatch sw = new StopWatch(jp.toShortString());
        try {
            sw.start(jp.toShortString());
            return jp.proceed();
        }
        finally {
            sw.stop();
            if (jp.getSignature() instanceof MethodSignature) {
                final StringBuilder sb = new StringBuilder('\'');
                sb.append(((MethodSignature) jp.getSignature()).getMethod()
                        .toGenericString());
                sb.append('\'');
                sb.append(" : running time (millis) = ");
                sb.append(sw.getTotalTimeMillis());
                logger.debug(sb.toString());
            } else {
                logger.debug(sw.shortSummary());
            }
        }
    }
}
